package org.deltaset.secured.domain;

import java.util.Date;
import java.util.List;
import javax.annotation.ManagedBean;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

/**
 *
 * @author dmakariev
 */
@ManagedBean
public class VisitRepositoryAddon extends AbstractRepository {

    public long countVisits() {
        return entityManager().createQuery("SELECT COUNT(o) FROM Visit o", Long.class).getSingleResult();
    }

    public List<Visit> findAllVisits() {
        return entityManager().createQuery("SELECT o FROM Visit o", Visit.class).getResultList();
    }

    public Visit findVisit(Long id) {
        if (id == null) {
            return null;
        }
        return entityManager().find(Visit.class, id);
    }

    public List<Visit> findVisitEntries(int firstResult, int maxResults) {
        return entityManager().createQuery("SELECT o FROM Visit o", Visit.class).setFirstResult(firstResult).setMaxResults(maxResults).getResultList();
    }

////////////    
    private TypedQuery<Visit> findVisitsByDescriptionAndVisitDate(String description, Date visitDate) {
        if (description == null || description.length() == 0) {
            throw new IllegalArgumentException("The description argument is required");
        }
        if (visitDate == null) {
            throw new IllegalArgumentException("The visitDate argument is required");
        }
        EntityManager em = entityManager();
        TypedQuery<Visit> q = em.createQuery("SELECT o FROM Visit AS o WHERE o.description = :description AND o.visitDate = :visitDate", Visit.class);
        q.setParameter("description", description);
        q.setParameter("visitDate", visitDate);
        return q;
    }

    private TypedQuery<Visit> findVisitsByDescriptionLike(String description) {
        if (description == null || description.length() == 0) {
            throw new IllegalArgumentException("The description argument is required");
        }
        description = description.replace('*', '%');
        if (description.charAt(0) != '%') {
            description = "%" + description;
        }
        if (description.charAt(description.length() - 1) != '%') {
            description = description + "%";
        }
        EntityManager em = entityManager();
        TypedQuery<Visit> q = em.createQuery("SELECT o FROM Visit AS o WHERE LOWER(o.description) LIKE LOWER(:description)", Visit.class);
        q.setParameter("description", description);
        return q;
    }

    private TypedQuery<Visit> findVisitsByVisitDateBetween(Date minVisitDate, Date maxVisitDate) {
        if (minVisitDate == null) {
            throw new IllegalArgumentException("The minVisitDate argument is required");
        }
        if (maxVisitDate == null) {
            throw new IllegalArgumentException("The maxVisitDate argument is required");
        }
        EntityManager em = entityManager();
        TypedQuery<Visit> q = em.createQuery("SELECT o FROM Visit AS o WHERE o.visitDate BETWEEN :minVisitDate AND :maxVisitDate", Visit.class);
        q.setParameter("minVisitDate", minVisitDate);
        q.setParameter("maxVisitDate", maxVisitDate);
        return q;
    }
}
